package cn.qzzg.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Redis配置
 */
// @EnableTransactionManagement    // 开启声明式事务
@Configuration
public class RedisConfig {
    @Resource
    private LettuceConnectionFactory redisConnectionFactory;

    /**
     * redis 模板类（工具类）
     *
     * @param redisConnectionFactory redis 连接工厂
     * @return 模板
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        /*
         * 序列化设置
         */
        // key、hash的key 采用 String序列化方式
        redisTemplate.setKeySerializer(RedisSerializer.string());
        redisTemplate.setHashKeySerializer(RedisSerializer.string());
        // value、hash的value 采用 Jackson 序列化方式
        redisTemplate.setValueSerializer(RedisSerializer.json());
        redisTemplate.setHashValueSerializer(RedisSerializer.json());

        redisTemplate.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }


    /**
     * 监听者容器 （负责管理线程池、消息分发给对应管道的监听者）
     * 可以动态设置订阅者和管道，通过这个特性可以不重启服务器的情况下
     * 动态设置订阅者和管道
     *
     * @param messageListenerAdapter 消息监听者
     */
    // @Bean
    public RedisMessageListenerContainer container(MessageListenerAdapter messageListenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        // 设置连接工厂
        container.setConnectionFactory(redisConnectionFactory);
        // 设置监听者绑定的管道
        List<Topic> topicList = new ArrayList<>();
        topicList.add(new PatternTopic("test"));
        // param1：监听者    param2：绑定管道
        container.addMessageListener(messageListenerAdapter, topicList);
        // container.removeMessageListener(messageListenerAdapter);    //删除管道
        return container;
    }

    /**
     * 消息侦听器适配器，能将消息委托给目标侦听器方法
     */
    // @Bean
    public MessageListenerAdapter listenerAdapter(MessageListener messageListener) {
        return new MessageListenerAdapter(messageListener);
    }
}
